UserScriptで<input>を使ってみる
数値とか時刻とかを簡単に入力できるUIが欲しい
基本形
code:script.js
import {mimicClick} from '../scrapbox-pointer-emulation@0.1.0/script.js';
export const datePrompt = (initialValue) => new Promise(async (resolve, reject) => {
const input = document.createElement('input');
input.type = 'date';
input.value= initialValue;
input.addEventListener('change', async () => {
resolve(input.valueAsNumber);
input.remove();
});
input.addEventListener('error', e => {
reject(e);
});
document.getElementById('editor').appendChild(input);
const {top, left, width, height} = input.getBoundingClientRect();
input.focus();
await mimicClick(window, {Y: top + height / 2, X: left + width / 2});
});
test code
code:js
(async () => {
const {datePrompt} = await import('/api/code/takker/UserScriptで<input>を使ってみる/script.js');
console.log(await datePrompt('2021-05-14'));
})();
2021-05-16
09:23:46 focus()を試してみる
09:50:50 だめだった
focus()単体も、mimicClick()とのあわせ技も効かなかった
10:22:43 windowに対して疑似クリックを実行すればうまくいくのでは?
click eventを処理しているのは<input>ではなくその中のshadow DOM
10:23:10 だめでした
2021-05-16 10:02:52 うまくいきそうな方法を見つけた
10:32:39 うまく行かなかった……
useRef()とuseEffect()で、<button>に対してclick処理を発火させたけど、何も起きなかった
<input>のshadow DOM内に対してclick eventを発さないとだめなのか?takker.icon
10:36:00 <date-picker>に対して発火させてもだめだった……
code:js
(async () => {
await import('/api/code/takker/UserScriptで<input>を使ってみる/script2.js');
const {mimicClick} = await import('/api/code/takker/scrapbox-pointer-emulation@0.1.0/script.js');
const datePicker= document.createElement('date-picker');
document.getElementById('editor').appendChild(datePicker);
const {right, bottom} = datePicker.getBoundingClientRect();
await mimicClick(datePicker, {Y: bottom - 2, X: right - 2});
})();
code:script2.js
import {html} from '../htm@3.0.4%2Fpreact/script.js';
import {useEffect, useRef} from '../preact@10.5.13/hooks.js';
import register from '../preact-custom-element@4.2.1/script.js';
const DatePicker = () => {
return html`
<style>
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.exmp-wrp {
position: relative;
width: 200px;
}
.btn-wrp {
display: inline-block;
width: 100%;
position: relative;
z-index: 10;
}
.btn-clck {
border: none;
background: transparent;
width: 100%;
padding: 10px;
}
.btn-clck::-webkit-calendar-picker-indicator {
right: -10px;
position: absolute;
width: 78px;
height: 40px;
color: rgba(204, 204, 204, 0);
opacity: 0
}
.btn-clck::-webkit-inner-spin-button {
-webkit-appearance: none;
}
.btn-clck::-webkit-clear-button {
margin-right:75px;
}
.btn {
height: 100%;
border: none;
padding: 13px;
position: absolute;
right: 0;
top: 0;
}
</style>
<div class="exmp-wrp">
<div class="btn-wrp">
<input type="date" class="btn-clck"/>
</div>
<button class="btn">Click me</button>
</div>
`;
};
register(DatePicker, 'date-picker', [], {shadow: true});
References